/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ACCESSIBILITY_ESPEAK_PROXY_H
#define ACCESSIBILITY_ESPEAK_PROXY_H

#include "speak_lib.h"
#include "hilog_wrapper.h"
#include <string>

#define ESPEAK_DATA_PATH "/etc"

const int LANGUAGE_NUM = 3;
const int VOICE_NUM = 4;

namespace OHOS {
namespace Accessibility {

class EspeakProxy {
public:
    static void Init();
    static void Release();

    /**
     * @brief 合成语音
     * @param text 合成文本
     */
    static bool Synthesize(const char *text);

    /**
     * @brief 设置语速
     * @param speed 语速，取值范围30-100，默认为50
     * @return true表示设置成功，false表示设置失败
     */
    static bool SetSpeed(int speed = 50);

    /**
     * @brief 设置音量
     * @param volume 音量，取值范围0-100，默认为100
     * @return true表示设置成功，false表示设置失败
     */
    static bool SetVolume(int volume = 100);
    

    /* 设置音调 */
    /**
     * @brief 设置基础音调
     * @param pitch 基础音调，取值范围0-100，默认为50
     * @return true表示设置成功，false表示设置失败
     */
    static bool SetBasePitch(int pitch = 50);

    /**
     * @brief 设置音调范围
     * @param range 音调范围，取值范围0-100，默认为50
     * @return true表示设置成功，false表示设置失败
     */
    static bool SetPitchRange(int range = 50);

    /**
     * @brief 预设音调选项
     * @param option 预设选项，取值范围0，1，2，分别为普通，高音且变化大，低音且单调。默认为0
     * @return true表示设置成功，false表示设置失败
     */
    static bool QuickSetPitch(int option);

    // static void ListVoices(){}

    static bool CheckPitch(int voice, int pitch); // 检查SetVoiceByName音调是否合法
    /**
     * @brief 设置voice
     * @param language 语言，取值范围0-2，默认为0; 0-简体中文，1-粤语， 2-英文
     * @param voice 语音，取值范围0-3，默认为0; 0-女声，1-男声，2-croak，3-whisper
     * @param pitch 音调，当voice取0或1时该参数有效，且voice为0时，取值范围为1-4；voice为1时，取值范围为1-7
     * @return true表示设置成功，false表示设置失败
     */
    static bool SetVoiceByName(int language = 0, int voice = 0, int pitch = 2);

    /**
     * @breif 切换语言
     * @param direction 方向，取值范围-1,1，-1表示向前切换，1表示向后切换
     * @return true表示切换成功，false表示切换失败
     */
    static bool NextLanguage(int direction);

    /**
     * @breif 切换声音
     * @param direction 方向，取值范围-1,1，0表示向前切换，1表示向后切换
     * @return true表示切换成功，false表示切换失败
     */
    static bool NextVoice(int direction);

    static int GetCurrentLanguage(){
        return currentLanguage_;
    }

    static int GetCurrentVoice(){
        return currentVoice_;
    }

    static void TestSpeakChinese(){
        Synthesize("你好，屏幕朗读声音测试");
    }

    static void TestSpeakEnglish(){
        Synthesize("Hello, Screen Reader Voice Test");
    }

    /**
     * @breif espeak是否正在合成语音
     * @return true表示正在合成，false表示没有正在合成
     */
    static bool IsPlaying()
    {
        return espeak_IsPlaying();
    }

    /**
     * @brief 等待合成结束
     */
    static void WaitSynth()
    {
        espeak_Synchronize();
    }

    static bool Cancel()
    {
        HILOG_DEBUG(ESPEAK_TAG "espeak Cancel");
        return espeak_Cancel() == 0;
    }

    /**
     * @brief 终止合成
     */
    static void Terminate()
    {
        HILOG_DEBUG(ESPEAK_TAG "espeak Terminate");
        espeak_Terminate();
    }

private:
    /**
     * @brief 提供给espeak的回调函数，espeak合成过程中调用该函数返回wav数据和事件
     * @param wav 合成过程中返回的wav数据
     * @param numsamples wav数据的采样点数
     * @param events 合成过程中返回的事件
     * @return 0表示继续合成，1则终止合成
     */
    static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events);

    static const std::string lan_[LANGUAGE_NUM];
    static const std::string v_[VOICE_NUM];
    static int currentLanguage_;
    static int currentVoice_;
    static int currentPitch_;
};

} // namespace Accessibility
} // namespace OHOS

#endif // ACCESSIBILITY_ESPEAK_PROXY_H